﻿using System.Collections.Generic;
using System.Linq;
using Framework.Core.Dependency.Domain;
using Framework.Core.Dependency.Visitor;
using Xunit;

namespace Framework.Tests.Core.Dependency
{
    public class DependencyVisitorTest
    {
        [Fact]
        public void Should_walk_with_cycle()
        {
            var sA = GetSolution("A");
            var sB = GetSolution("B");
            var sC = GetSolution("B");

            var p1 = GetProject("1");
            var p2 = GetProject("2");

            var m1 = new Module("1", "1");
            var m2 = new Module("2", "2");
            var m7 = new Module("7", "7");
            var m8 = new Module("8", "8");

            p1.AddModule(m2);
            p2.AddModule(m1);
            p2.AddModule(m7);
            p2.AddModule(m8);

            const string branch = "pouet";
            sA.AddProject(p1, branch);

            sB.AddProject(p2, branch);

            var p3 = GetProject("3");
            var p4 = GetProject("4");
            var p5 = GetProject("5");

            var m3 = new Module("3", "3");
            var m4 = new Module("4", "4");
            var m5 = new Module("5", "5");

            sC.AddProject(p3, branch);
            sC.AddProject(p4, branch);
            sC.AddProject(p5, branch);

            p3.AddModule(m4);
            p4.AddModule(m5);
            p5.AddModule(m3);

            var solutions = new List<Solution> { sA, sB, sC };

            var allBuildProjects = solutions.SelectMany(x => x.Projects).ToList();
            var dependencyVisitor = new DependencyVisitor(allBuildProjects, new List<string> { @"c:\pouet\8.dll" });

            foreach (var buildProject in allBuildProjects)
            {
                buildProject.Accept(dependencyVisitor);
            }

            Assert.Equal(p1, p2.Dependencies.First());
            Assert.Equal(p2, p1.Dependencies.First());
            Assert.DoesNotContain(m8, dependencyVisitor.ModulesNotFound);
            Assert.Contains(m7, dependencyVisitor.ModulesNotFound);
            Assert.Equal(1, dependencyVisitor.ModulesNotFound.Count());
        }

        private static Project GetProject(string name)
        {
            return new Project(name, ".cspj", "c:\toto.cspj", name, Language.CSharp);
        }

        private static Solution GetSolution(string name)
        {
            return new Solution(name, "sln", @"c:\pouet\A.sln", Language.CSharp, @"c:\pouet");
        }
    }
}
